package com.david.flowable.service.Impl;

import com.david.flowable.flowfactory.FlowServiceFactory;
import com.david.flowable.pojo.dto.FlowViewDTO;
import com.david.flowable.pojo.vo.FormFlowVO;
import com.david.flowable.service.FlowDefinitionService;
import com.david.system.mapper.UserMapper;
import com.david.system.pojo.Entity.JobEntity;
import com.david.system.pojo.Entity.UserEntity;
import com.david.system.pojo.Entity.UserInfo;
import org.apache.commons.io.IOUtils;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Service
public class FlowDefinitionServiceImpl extends FlowServiceFactory implements FlowDefinitionService {

    @Autowired
    private UserMapper userMapper;
    private static final String BPMN_FILE_SUFFIX = ".bpmn";
    @Override
    public String saveXml(String name, String category, InputStream in) {
        Deployment deployment = repositoryService.createDeployment().addInputStream(name+BPMN_FILE_SUFFIX,in).name(name).category(category).deploy();
        System.out.println(deployment.getId());
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
        repositoryService.setProcessDefinitionCategory(processDefinition.getId(),category);
        System.out.println(processDefinition.getId());
        return processDefinition.getId();
    }

    @Override
    public List<UserInfo> searchUsers(List<Long> ids) {
        List<UserInfo> userInfos = userMapper.selectUserByIds(ids);
        System.out.println(userInfos);
        return userInfos;
    }

    @Override
    public List<JobEntity> searchJobs(List<Integer> ids) {
        List<JobEntity> jobs = userMapper.selectJobByIds(ids);
        return jobs;
    }

    @Override
    public Map<String, Object> getXmlAndNode(String deployId, String proInsId)  {
        try{
            List<FlowViewDTO> flowViewDTOList = new ArrayList<>();
            if (!Objects.equals(proInsId, "empty")) {
                // 已完成列表
                List<HistoricActivityInstance> finishedList = historyService.createHistoricActivityInstanceQuery().processInstanceId(proInsId).finished().list();
                finishedList.forEach( e -> {
                    FlowViewDTO flowViewDTO = new FlowViewDTO();
                    flowViewDTO.setKey(e.getActivityId());
                    flowViewDTO.setCompleted(true);
                    flowViewDTOList.add(flowViewDTO);
                });
                // 未完成列表
                List<HistoricActivityInstance> unfinishedList = historyService.createHistoricActivityInstanceQuery().processInstanceId(proInsId).unfinished().list();
                unfinishedList.forEach( e -> {
                    FlowViewDTO flowViewDTO = new FlowViewDTO();
                    flowViewDTO.setKey(e.getActivityId());
                    flowViewDTO.setCompleted(false);
                    flowViewDTOList.add(flowViewDTO);
                });
            }
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployId).singleResult();
            InputStream xml = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(),processDefinition.getResourceName());
            String xmlStr = IOUtils.toString(xml, StandardCharsets.UTF_8);

            Map<String,Object> map = new HashMap<>();
            map.put("nodeData", flowViewDTOList);
            map.put("xmlData", xmlStr);
            return map;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Map<String, Object> getXml(String flowId) {
        try{
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(flowId).singleResult();
            InputStream xml = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(),processDefinition.getResourceName());
            String xmlStr = IOUtils.toString(xml, StandardCharsets.UTF_8);
            Map<String,Object> map = new HashMap<>();
            map.put("xmlData", xmlStr);
            return map;
        } catch (IOException e){
            throw  new RuntimeException(e);
        }

    }



}
